package westh.ilib.service;

import java.io.File;
import java.util.Arrays;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.mule.extras.client.MuleClient;
import org.mule.umo.UMOMessage;

import westh.ilib.bean.croDomainSearch.Resource;
import westh.ilib.bean.surveyReport.*;
import westh.ilib.service.surveyReport.documentSearch.*;
import westh.ilib.service.surveyReport.queryGeneration.*;
import westh.ilib.service.surveyReport.reportGeneration.*;
import westh.config.Config;
/**
 * getSurveyReport service
 * 
 * @author ZhangYanxing 2010-8-19
 */
public class SurveyReportService {
	/********** file path configuration **********/
	//!!!change the localDataPath when data directory moved
//	static final String localDataPath = "E:\\workspace\\";
	static final String localDataPath = "D:\\tmp\\SurveyReport\\";
	
	// directory path of local dataset
	static final String xmlPath = localDataPath + "xml\\";

	// directory path of local dataset's index
	static final String indexPath = localDataPath + "index\\";

	// directory of index of wordNet synonyms
	static final String wordnetIndexPath = localDataPath + "\\wordnetIndex";

	// files of classifier training -- human-tagged, training set, test set
	final static String taggedPath = localDataPath + "\\sentence-tagged.arff";
	final static String trainingSetPath = localDataPath + "\\sentence-train.arff";
	final static String testSetPath = localDataPath + "\\sentence-test.arff";

	//get clouds Ip address
	final static String localhostUrl = Config.get("localhostUrl");
	final static String remoteUrl = Config.get("remoteUrl");
	
	/********************************************/
	/**
	 * @author Zhang Yanxing getSurveyReport in the local dataset
	 * @param String
	 *            str: survey keywords
	 * @return SurveyReport see{@link westh.ilib.bean.surveyReport.SurveyReport}
	 *         2010-8-19
	 */
	public static SurveyReport getSurveyReport(String str) {
		org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
				.getLog(SurveyReportService.class);

		SurveyReport report = new SurveyReport();

		// query generation
		Generator gen = new Generator(str);
		Query query = gen.generator(wordnetIndexPath);

		// document search in local dataset
		int n = 50;
		float[] scores = new float[n];
		String[] years = new String[n];
		String[] confs = new String[n];
		String[] titles = new String[n];
		String[] keywords = new String[n];
		String[] summarys = new String[n];
		int[] rscType = new int[n];
		docSearcher.search(indexPath, query, n, scores, years, confs, titles,
				keywords, summarys, rscType);

		// survey report generation
		// 1) survey summary generation
		SummGenerator summGen = new SummGenerator(n, scores, years, confs,
				titles, keywords, summarys, rscType);
		report.setSurveyAbstract(summGen.generator());

		// 2) survey statistic generation
		RscTypeStat stat = summGen.calculate();
		report.setBookNum(stat.bookNum);
		report.setConfNum(stat.confNum);
		report.setJournalNum(stat.journalNum);
		report.setPatentNum(stat.patentNum);
		report.setSoftwCopyrNum(stat.softwCopyrNum);
		report.setStandardNum(stat.standardNum);
		report.setTechReportNum(stat.techReportNum);

		return report;
	}

	/**
	 * @author Zhang Yanxing getSurveyReport: search using croDomainSearch
	 * @param String
	 *            str: survey keywords
	 * @param String
	 *            [] resType: book 1; conf 2; journal 3; patent 4; softwCopyr 5;
	 *            techReport 6; standard 7
	 * @param String
	 *            [] resField: CNL 1; OAI(Tsinghua) 2; CALIS 3; 清华大学水利 4; TagSys
	 *            5
	 * @return SurveyReport see{@link westh.ilib.bean.surveyReport.SurveyReport}
	 */
	public static SurveyReport getSurveyReport(String str, String[] resType,
			String[] resField) {
		org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
				.getLog(SurveyReportService.class);

		// search documents by croDomainSearch
		try {
			// generate croDomainSearch query
			JSONObject queryJson = new JSONObject();

			JSONArray resTypeArray = new JSONArray();
			for (int i = 0; i < resType.length; i++) {
				resTypeArray.add(resType[i].toString());
			}

			JSONArray resFieldArray = new JSONArray();
			for (int i = 0; i < resField.length; i++) {
				resFieldArray.add(resField[i].toString());
			}

			queryJson.put("query", str);
			queryJson.put("rscTypeList", resTypeArray);
			queryJson.put("rscFieldList", resFieldArray);

			String queryJsonStr = queryJson.toString();
			System.out.println(queryJsonStr);

			// search documents by cross domain search
			ResourceService res = new ResourceService();
			String result = res.getResouceListByJsonMul(queryJsonStr, log);
			JSONObject searchResult = JSONObject.fromObject(result);
			JSONArray searchDocs = searchResult.getJSONArray("result");

			// add hit-docs from croDomainSearch into local index
			if (searchDocs.size() > 0) {
				File indexDir = new File(indexPath);
				IndexWriter writer = new IndexWriter(
						FSDirectory.open(indexDir), new StandardAnalyzer(
								Version.LUCENE_CURRENT), false,
						IndexWriter.MaxFieldLength.LIMITED);
				log.debug("!!! searched " + searchDocs.size() + "docs");
				for (int i = 0; i < searchDocs.size(); i++) {
					writer.addDocument(FileDocument
							.Document(searchDocs.get(i)));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		SurveyReport report = new SurveyReport();

		// query generation
		Generator gen = new Generator(str);
		Query query = gen.generator(wordnetIndexPath);

		// document search
		int n = 50;
		float[] scores = new float[n];
		String[] years = new String[n];
		String[] confs = new String[n];
		String[] titles = new String[n];
		String[] keywords = new String[n];
		String[] summarys = new String[n];
		int[] rscType = new int[n];
		docSearcher.search(indexPath, query, n, scores, years, confs, titles,
				keywords, summarys, rscType);

		// survey report generation
		// 1) survey summary generation
		SummGenerator summGen = new SummGenerator(n, scores, years, confs,
				titles, keywords, summarys, rscType);
		report.setSurveyAbstract(summGen.generator());

		// 2) survey statistic generation
		RscTypeStat stat = summGen.calculate();
		report.setBookNum(stat.bookNum);
		report.setConfNum(stat.confNum);
		report.setJournalNum(stat.journalNum);
		report.setPatentNum(stat.patentNum);
		report.setSoftwCopyrNum(stat.softwCopyrNum);
		report.setStandardNum(stat.standardNum);
		report.setTechReportNum(stat.techReportNum);

		return report;
	}

	/*
	 * public static void DatasetPreparation(){ String xmlPath =
	 * "E:\\zhyx\\SurveyReport\\xml\\"; String trecPath =
	 * "E:\\zhyx\\SurveyReport\\trec\\"; String idmappath =
	 * "E:\\zhyx\\SurveyReport\\idmap.txt"; docTransformer.xml2trec(xmlPath,
	 * trecPath, idmappath); }
	 */

	/**
	 * index the local dataset (in xmlPath) running before getSurveyReport()
	 */
	public static void DatasetIndex() {
		Indexer.index(xmlPath, indexPath);
	}

	/**
	 * get survey history result
	 * 
	 * @author Zhang Yanxing
	 * @param 2010-8-20
	 */
	public static void getSurveyHistory(String keywords, String[] rscType,
			String[] rscField) {
		String resTypeStr = Arrays.toString(rscType);
		String resTypeRequestStr = "";
		for (int i = 1; i <= 7; i++) {
			if (resTypeStr.indexOf(Integer.toString(i)) != -1) {
				resTypeRequestStr += "1";
			} else {
				resTypeRequestStr += "0";
			}
		}

		String resFieldStr = Arrays.toString(rscField);
		String resFieldRequestStr = "";
		for (int i = 1; i <= 5; i++) {
			if (resFieldStr.indexOf(Integer.toString(i)) != -1) {
				resFieldRequestStr += "1";
			} else {
				resFieldRequestStr += "0";
			}
		}

		JSONObject requestData = new JSONObject();
		requestData.put("query", keywords);
		requestData.put("rscTypeList", resTypeRequestStr);
		requestData.put("fieldList", resFieldRequestStr);

		JSONObject requestObject = new JSONObject();
		requestObject.put("methodName", "getSurveyReport");
		requestObject.put("jsonStr", requestData.toString());

		try {
			String inputStr = requestObject.toString();
			String outString = "";

			MuleClient clientD = new MuleClient();
			// call ulas service
			UMOMessage umo = clientD.send("axis:http://"+remoteUrl+":9281/Service/ulasService?method=rulesControl",	inputStr, null);
			outString = (String) umo.getPayload();
			
			JSONObject resultObject = JSONObject.fromObject(outString);
			JSONArray resultArrays = JSONArray.fromObject(resultObject);
			
			SurveyReport [] reports = new SurveyReport[ resultArrays.size() ];
			for(int i =0; i< resultArrays.size(); i++){
				reports[i] = new SurveyReport();
				reports[i].setBookNum( ((JSONObject)resultArrays.get(i)).getInt("survBookNum"));
				reports[i].setConfNum(((JSONObject)resultArrays.get(i)).getInt("survConfNum"));
				reports[i].setJournalNum(((JSONObject)resultArrays.get(i)).getInt("survJournalNum"));
				reports[i].setPatentNum(((JSONObject)resultArrays.get(i)).getInt("survPatentNum"));
				reports[i].setSoftwCopyrNum(((JSONObject)resultArrays.get(i)).getInt("survSortwCopyrNum"));
				reports[i].setStandardNum(((JSONObject)resultArrays.get(i)).getInt("survStandarNum"));
				reports[i].setTechReportNum(((JSONObject)resultArrays.get(i)).getInt("survTechReportNum"));
				reports[i].setSurveyAbstract(((JSONObject)resultArrays.get(i)).getString("survAbstract"));
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	public static void main(String[] args) {
		/*
		// index the local dataset, only the first time
		SurveyReportService.DatasetIndex();

		// unit test: testcase 1
		// get SurveyReport in local dataset
		SurveyReport report1 = SurveyReportService
				.getSurveyReport("search engine");
		System.out.println("book: " + report1.getBookNum());
		System.out.println("conference: " + report1.getConfNum());
		System.out.println("Journal: " + report1.getJournalNum());
		System.out.println("patent: " + report1.getPatentNum());
		System.out.println("softwCopyr: " + report1.getSoftwCopyrNum());
		System.out.println("standard: " + report1.getStandardNum());
		System.out.println("techReport: " + report1.getTechReportNum());
		System.out.println("surveyAbstract:\n" + report1.getSurveyAbstract());

		// unit test: testcase 2
		// get SurveyReport using croDomainSearch
		String[] resType = new String[7];
		resType[0] = "1";
		resType[1] = "2";
		resType[2] = "3";
		resType[3] = "4";
		resType[4] = "5";
		resType[5] = "6";
		resType[6] = "7";

		String[] resField = new String[1];
		
		resField[0] = "5";

		SurveyReport report2 = SurveyReportService.getSurveyReport(
				"search engine", resType, resField);

		System.out.println("book: " + report2.getBookNum());
		System.out.println("conference: " + report2.getConfNum());
		System.out.println("Journal: " + report2.getJournalNum());
		System.out.println("patent: " + report2.getPatentNum());
		System.out.println("softwCopyr: " + report2.getSoftwCopyrNum());
		System.out.println("standard: " + report2.getStandardNum());
		System.out.println("techReport: " + report2.getTechReportNum());
		System.out.println("surveyAbstract" + report2.getSurveyAbstract());
		*/
	}
}